//
//  CellSelector.swift
//  moapp
//
//  Created by zhu xietong on 2018/4/9.
//


import Foundation
//import Regex
import Eelay
public struct Cellkey{
    public static let header:String = "header"
    public static let ID:String = "ID"

}

public enum soappError: Error {
    case cellSelector(message:String)
}

class SelItem {
    var values = [String]()
    var key:String = ""
    var rawValue = ""
    
    func updateRawValue(newValue:String)
    {
        self.rawValue = newValue
        let value_reg = Regex("(?:<)(\\S*?)(?:>)")
        var value_tag = ""
        
        let results = value_reg.allMatches(in: rawValue)
        for one in results{
            let value_string = one.captures
            for one_value in value_string{
                if let _value = one_value{
                    value_tag = _value
                }
            }
        }
        self.values = value_tag.components(separatedBy: ",")
        self.key = rawValue.replacingAll(matching: value_reg, with: "")
    }
    
    var selType:SelItemType = .unkown
    var cellType:String
    init(rawValue:String,cellType:String) {
        
        self.cellType = cellType

        self.updateRawValue(newValue: rawValue)
        self.selType = SelItemType.create(keySring: rawValue)
    }
    
    public func isMach(item:NSMutableDictionary)->Bool{
        if let cellTp = item["__cell__"] as? String
        {
            return (cellTp == "\(self.cellType)")
        }
        
        var isMath = false
        switch self.selType {
        case .default:
            isMath = true
        case .sections:
            let section = "section" + item["__section__",""]
            if self.values.contains(section)
            {
                isMath = true
            }
        case .cell:
            if let keys = item.allKeys as? [String]
            {
                for one_key in keys
                {
                    if one_key == self.key{
                        let value = item["\(one_key)",""]
                        if self.values.contains(value){
                            isMath = true
                        }
                    }
                }
            }
        default:
            break
        }
        
        return isMath
    }
}
enum SelItemType {
    case `default`
    case sections
    case cell
    case unkown
    
    var priority:Int{
        get{
            switch self {
            case .cell:
                return 100
            case .sections:
                return 90
            case .default:
                return 80
            default:
                return 10
            }
        }
    }
    
    static func create(keySring:String)->SelItemType{
        if keySring == "<default>"
        {
            return .default
        }
        if  Regex("\\S+?<\\S+?>").matches(keySring){
            return .cell
        }
        if  Regex("^<section\\S+?").matches(keySring){
            return .sections
        }
        return .unkown
    }
}

public class CellSelector{
    //header选择器
    public static func headerIdentify(section:Int,item:NSMutableDictionary,selector:[String:Any])->String?{
        item["__section__"] = section
        if let cellId = item.object(forKey: "__header__") as? String
        {
            return cellId
        }
        
        var item_list = [SelItem]()
        for sel_key in selector.keys{
            if let cellTypeObj = selector[sel_key]
            {
                let sitem = SelItem(rawValue: sel_key,cellType:"\(cellTypeObj)")
                item_list.append(sitem)
            }
        }
        item_list = item_list.sorted { (s1, s2) -> Bool in
            return (s1.selType.priority > s2.selType.priority)
        }
        
        var haveLoadCell = false
        var cellTypeID:String? = nil
        for sel in item_list
        {
            if !haveLoadCell{
                if sel.isMach(item: item){
                    
                    cellTypeID = sel.rawValue
                    item["__header__"] = sel.rawValue
                    haveLoadCell = true
                    break
                }
            }
        }
        if let tp = cellTypeID
        {
            return "\(tp)"
        }
        return nil
    }
    
    
    
    //cell选择器
    public static func cellTypeIdentify(indexPath:IndexPath,item:NSMutableDictionary,selector:[String:Any])->String?{
        item["__row__"] = indexPath.row
        item["__section__"] = indexPath.section
        if let cellId = item.object(forKey: "__cell__") as? String
        {
            return cellId
        }
        
        var item_list = [SelItem]()
        for sel_key in selector.keys{
            if let cellTypeObj = selector[sel_key]
            {
                let sitem = SelItem(rawValue: sel_key,cellType:"\(cellTypeObj)")
                item_list.append(sitem)
            }
        }
        item_list = item_list.sorted { (s1, s2) -> Bool in
            return (s1.selType.priority > s2.selType.priority)
        }
        
        var haveLoadCell = false
        var cellTypeID:String? = nil
        for sel in item_list
        {
            if !haveLoadCell{
                if sel.isMach(item: item){
                    
                    cellTypeID = sel.rawValue
                    item["__cell__"] = sel.rawValue
                    haveLoadCell = true
                    break
                }
            }
        }
        if let tp = cellTypeID
        {
            return "\(tp)"
        }
        return nil
    }
    
    static public func createModel(sections:TP.section)->NSMutableDictionary{
        let result = NSMutableDictionary()
        var headers = [String:[String:Any]]()
        for (index,section) in sections.enumerated()
        {
        
            if let h = section.first{
                if h.contains(where: { (k,v) -> Bool in
                    return k  == "header" && "\(v)" == "YES"
                }){
                    var newSec = section
                    newSec.remove(at: 0)
                    headers["section\(index)"] = h

                    result.setObject(section.mutable_array, forKey: "section\(index)" as NSCopying)
                }else{
                    result.setObject(section.mutable_array, forKey: "section\(index)" as NSCopying)                }
                
            }else{
                result.setObject(section.mutable_array, forKey: "section\(index)" as NSCopying)
            }
        }
        result.setObject(headers.mutable_dictionary, forKey: "headers" as NSCopying)
        return result
    }
    
}



